#include "Archer.h"
#include "GameGlobal.h"
#include "InlineFunc.h"
#include "CocosHelper.h"

#include <algorithm>

#include "SimpleAudioEngine.h"
using namespace cocos2d;
using namespace std;
using namespace CocosDenshion;


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void CArcher::_BuildArcherFrame(const ArcherInitData &archerData)
{
    
    // …ÌÃÂ
    //pNewArcher->_InitState();
    
    
    strcpy(m_frameInfo[ARCHER_INDEX_BODY]._szSpritePath, archerData._dataBody._name);
    m_frameInfo[ARCHER_INDEX_BODY]._bUseFrame      = archerData._dataBody._bUseFrame;
    m_frameInfo[ARCHER_INDEX_BODY]._ptSize         = archerData._dataBody._ptSize;
    m_frameInfo[ARCHER_INDEX_BODY]._ptAnchor       = archerData._dataBody._ptAnchor;
    m_frameInfo[ARCHER_INDEX_BODY]._ptAnchorParent = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_BODY]._ptPos          = archerData._dataBody._ptPos;
    m_frameInfo[ARCHER_INDEX_BODY]._startRot       = 0;
    m_frameInfo[ARCHER_INDEX_BODY]._zOrder         = ARCHER_ZORDER_BODY;
    
    
    m_frameInfo[ARCHER_INDEX_NECK]._szSpritePath[0] = 0;
    m_frameInfo[ARCHER_INDEX_NECK]._ptSize         = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_NECK]._ptAnchor       = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_NECK]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_BODY]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_NECK]._ptPos          = archerData._dataHead._ptPos;
    m_frameInfo[ARCHER_INDEX_NECK]._startRot       = 0;
    m_frameInfo[ARCHER_INDEX_NECK]._zOrder         = 0;
    
    
    // Õ∑
    strcpy(m_frameInfo[ARCHER_INDEX_HEAD]._szSpritePath, archerData._dataHead._name);
    m_frameInfo[ARCHER_INDEX_HEAD]._bUseFrame      = archerData._dataHead._bUseFrame;
    m_frameInfo[ARCHER_INDEX_HEAD]._ptSize         = archerData._dataHead._ptSize;
    m_frameInfo[ARCHER_INDEX_HEAD]._ptAnchor       = archerData._dataHead._ptAnchor;
    m_frameInfo[ARCHER_INDEX_HEAD]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_NECK]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_HEAD]._ptPos          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_HEAD]._startRot       = 0;
    m_frameInfo[ARCHER_INDEX_HEAD]._zOrder         = ARCHER_ZORDER_HEAD;
    
    
    
    m_frameInfo[ARCHER_INDEX_SHOULDER]._szSpritePath[0] = 0;
    m_frameInfo[ARCHER_INDEX_SHOULDER]._ptSize          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_SHOULDER]._ptAnchor        = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_SHOULDER]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_BODY]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_SHOULDER]._ptPos           = archerData._dataArm._ptPos;
    m_frameInfo[ARCHER_INDEX_SHOULDER]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_SHOULDER]._zOrder          = 0;
    
    
    
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._szSpritePath[0] = 0;
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._ptSize          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._ptAnchor        = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_SHOULDER]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._ptPos           = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._zOrder          = 0;
    
    
    // ◊Û±€
    strcpy(m_frameInfo[ARCHER_INDEX_LEFTARM]._szSpritePath, archerData._dataArm._name);
    m_frameInfo[ARCHER_INDEX_LEFTARM]._bUseFrame      = archerData._dataArm._bUseFrame;
    m_frameInfo[ARCHER_INDEX_LEFTARM]._ptSize          = archerData._dataArm._ptSize;
    m_frameInfo[ARCHER_INDEX_LEFTARM]._ptAnchor        = archerData._dataArm._ptAnchor;
    m_frameInfo[ARCHER_INDEX_LEFTARM]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_LEFTARMBONE]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_LEFTARM]._ptPos           = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTARM]._startRot        = 180;
    m_frameInfo[ARCHER_INDEX_LEFTARM]._zOrder          = ARCHER_ZORDER_LEFTARM;
    
    
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._szSpritePath[0] = 0;
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._ptSize          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._ptAnchor        = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_SHOULDER]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._ptPos           = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._zOrder          = 0;
    
    // ”“±€
    strcpy(m_frameInfo[ARCHER_INDEX_RIGHTARM]._szSpritePath, m_frameInfo[ARCHER_INDEX_LEFTARM]._szSpritePath);
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._bUseFrame      = m_frameInfo[ARCHER_INDEX_LEFTARM]._bUseFrame;
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._ptSize          = m_frameInfo[ARCHER_INDEX_LEFTARM]._ptSize;
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._ptAnchor        = m_frameInfo[ARCHER_INDEX_LEFTARM]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._ptAnchorParent  = m_frameInfo[ARCHER_INDEX_RIGHTARMBONE]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._ptPos           = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_RIGHTARM]._zOrder          = ARCHER_ZORDER_RIGHTARM;
    
    
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._szSpritePath[0] = 0;
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._ptSize          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._ptAnchor        = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_LEFTARM]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._ptPos           = archerData._dataHand._ptPos;
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._startRot        = 180;
    m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._zOrder          = 0;
    
    // ◊Û ÷
    strcpy(m_frameInfo[ARCHER_INDEX_LEFTHAND]._szSpritePath, archerData._dataHand._name);
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._bUseFrame       = archerData._dataHand._bUseFrame;
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptSize          = archerData._dataHand._ptSize;
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptAnchor        = archerData._dataHand._ptAnchor;
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_LEFTHANDBONE]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptPos           = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_LEFTHAND]._zOrder          = ARCHER_ZORDER_LEFTHAND;
    
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._szSpritePath[0] = 0;
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._ptSize          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._ptAnchor        = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_RIGHTARM]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._ptPos           = archerData._dataHand._ptPos;
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._zOrder          = 0;
    
    // ”“ ÷
    strcpy(m_frameInfo[ARCHER_INDEX_RIGHTHAND]._szSpritePath, m_frameInfo[ARCHER_INDEX_LEFTHAND]._szSpritePath);
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._bUseFrame       = m_frameInfo[ARCHER_INDEX_LEFTHAND]._bUseFrame;
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._ptSize          = m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptSize;
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._ptAnchor        = m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._ptAnchorParent  = m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._ptPos           = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_RIGHTHAND]._zOrder          = ARCHER_ZORDER_RIGHTHAND;
    
    
    
    // π≠º˝
    strcpy(m_frameInfo[ARCHER_INDEX_BOW]._szSpritePath, archerData._dataBow._name);
    m_frameInfo[ARCHER_INDEX_BOW]._bUseFrame       = archerData._dataBow._bUseFrame;
    m_frameInfo[ARCHER_INDEX_BOW]._ptSize          = archerData._dataBow._ptSize;
    m_frameInfo[ARCHER_INDEX_BOW]._ptAnchor        = archerData._dataBow._ptAnchor;
    m_frameInfo[ARCHER_INDEX_BOW]._ptAnchorParent = m_frameInfo[ARCHER_INDEX_RIGHTHAND]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_BOW]._ptPos           = archerData._dataBow._ptPos;
    m_frameInfo[ARCHER_INDEX_BOW]._startRot        = 0;
    m_frameInfo[ARCHER_INDEX_BOW]._zOrder          = ARCHER_ZORDER_BOW;
    
    m_frameInfo[ARCHER_INDEX_ARROW]._szSpritePath[0] = NULL;
    m_frameInfo[ARCHER_INDEX_ARROW]._bUseFrame       = false;
    m_frameInfo[ARCHER_INDEX_ARROW]._ptSize          = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_ARROW]._ptAnchor        = ccp(0, 0);
    m_frameInfo[ARCHER_INDEX_ARROW]._ptAnchorParent  = m_frameInfo[ARCHER_INDEX_LEFTHAND]._ptAnchor;
    m_frameInfo[ARCHER_INDEX_ARROW]._ptPos           = archerData._dataBow._ptPos;
    m_frameInfo[ARCHER_INDEX_ARROW]._startRot        = -90;
    m_frameInfo[ARCHER_INDEX_ARROW]._zOrder          = ARCHER_ZORDER_ARROW;
    
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_InitFrames(ArcherFrameInfo frameInfo[ARCHER_INDEX_MAX], bool bFlip, bool bLoadTexture)
{
    Matrix4X3 mOrg;		// Œª÷√¡Ÿ ±±‰¡ø
	Matrix4X3 mRot;		// –˝◊™¡Ÿ ±±‰¡ø
	Quaternion qRot;	// –˝◊™Àƒ‘™ ˝£¨”√ªßππ‘Ï–˝◊™æÿ’Û
    
    
	ArcherFrameInfo *pCurFrameInfo = frameInfo;
    
	for(int i=0; i<ARCHER_INDEX_MAX; i++)
	{
        if(bLoadTexture)
        {
            m_apFrames[i] = new Frame;
        }
        
		if( 0 != pCurFrameInfo->_szSpritePath[0])
		{
            if(i == ARCHER_INDEX_BOW)
            {
                if(bLoadTexture)
                {
                    if(pCurFrameInfo->_bUseFrame)
                    {
                        m_pSprBow = CSpriteBow::spriteWithSpriteFrameName(pCurFrameInfo->_szSpritePath);
                    }
                    else
                    {
                        m_pSprBow = CSpriteBow::spriteWithFile(pCurFrameInfo->_szSpritePath);
                    }
                    
                }
                
                m_apFrames[i]->_pSprBone = m_pSprBow;
            }
            else
            {
                if(bLoadTexture)
                {
                    if(pCurFrameInfo->_bUseFrame)
                    {
                        m_apFrames[i]->_pSprBone = CCSprite::spriteWithSpriteFrameName(pCurFrameInfo->_szSpritePath);
                    }
                    else
                    {
                        m_apFrames[i]->_pSprBone = CCSprite::spriteWithFile(pCurFrameInfo->_szSpritePath);
                    }
                    
                }
                
                
                
                if(i == ARCHER_INDEX_HEAD || i == ARCHER_INDEX_BODY)
                {
                    if(bFlip)
                    {
                        m_apFrames[i]->_pSprBone->setFlipX(true);
                    }
                    else
                    {
                        m_apFrames[i]->_pSprBone->setFlipX(false);
                    }
                }
            }
            
            if(bLoadTexture)
            {
                addChild(m_apFrames[i]->_pSprBone, pCurFrameInfo->_zOrder);
            }
			
            
			m_apFrames[i]->_pSprBone->setAnchorPoint(ccp(pCurFrameInfo->_ptAnchor.x/pCurFrameInfo->_ptSize.x,(pCurFrameInfo->_ptSize.y - pCurFrameInfo->_ptAnchor.y)/pCurFrameInfo->_ptSize.y));
		}
        else
        {
            if(i != ARCHER_INDEX_ARROW)
            {
                m_apFrames[i]->_pSprBone = NULL;
            }
            else
            {
                if(m_apFrames[i]->_pSprBone != NULL)
                {
                    if(bFlip)
                    {
                        m_apFrames[i]->_pSprBone->setFlipX(true);
                    }
                    else
                    {
                        m_apFrames[i]->_pSprBone->setFlipX(false);
                    }
                }
                
            }
        }
        
		mOrg.Reset();
		mOrg.SetupTranslation(Vector3D(pCurFrameInfo->_ptPos.x - pCurFrameInfo->_ptAnchorParent.x, pCurFrameInfo->_ptAnchorParent.y-pCurFrameInfo->_ptPos.y, 0));
		qRot.SetRotateZ(CC_DEGREES_TO_RADIANS(pCurFrameInfo->_startRot));
        
        if(bFlip)
        {
            Quaternion q2;
            q2.SetRotateY(3.1415926);
            qRot *= q2;
        }
		mRot.FromQuaternion(qRot);
		m_apFrames[i]->_matOriginal  = mRot * mOrg;
	
        pCurFrameInfo++;

	}
	
    
	    /*
	m_apFrames[ARCHER_INDEX_BODY]->_pChild = m_apFrames[ARCHER_INDEX_NECK];
    m_apFrames[ARCHER_INDEX_NECK]->_pChild = m_apFrames[ARCHER_INDEX_HEAD];
	m_apFrames[ARCHER_INDEX_NECK]->_pSibling = m_apFrames[ARCHER_INDEX_SHOULDER];
    m_apFrames[ARCHER_INDEX_SHOULDER]->_pChild = m_apFrames[ARCHER_INDEX_LEFTARMBONE];
	m_apFrames[ARCHER_INDEX_LEFTARMBONE]->_pSibling = m_apFrames[ARCHER_INDEX_RIGHTARMBONE];
    
	m_apFrames[ARCHER_INDEX_LEFTARMBONE]->_pChild = m_apFrames[ARCHER_INDEX_LEFTARM];
	m_apFrames[ARCHER_INDEX_LEFTARM]->_pChild = m_apFrames[ARCHER_INDEX_LEFTHANDBONE];
    m_apFrames[ARCHER_INDEX_LEFTHANDBONE]->_pChild = m_apFrames[ARCHER_INDEX_LEFTHAND];
    
    m_apFrames[ARCHER_INDEX_RIGHTARMBONE]->_pChild = m_apFrames[ARCHER_INDEX_RIGHTARM];
	m_apFrames[ARCHER_INDEX_RIGHTARM]->_pChild = m_apFrames[ARCHER_INDEX_RIGHTHANDBONE];
    m_apFrames[ARCHER_INDEX_RIGHTHANDBONE]->_pChild = m_apFrames[ARCHER_INDEX_RIGHTHAND];
	m_apFrames[ARCHER_INDEX_RIGHTHAND]->_pChild = m_apFrames[ARCHER_INDEX_BOW];
     */
    
    if(bLoadTexture)
    {
        if(NULL != m_pParentFrame)
        {
            delete m_pParentFrame;
        }
        
        m_pParentFrame = m_apFrames[ARCHER_INDEX_BODY];
        m_pParentFrame->AddChild(m_apFrames[ARCHER_INDEX_NECK]);
        m_pParentFrame->AddChild(m_apFrames[ARCHER_INDEX_SHOULDER]);
        m_apFrames[ARCHER_INDEX_NECK]->AddChild(m_apFrames[ARCHER_INDEX_HEAD]);
        m_apFrames[ARCHER_INDEX_SHOULDER]->AddChild(m_apFrames[ARCHER_INDEX_LEFTARMBONE]);
        m_apFrames[ARCHER_INDEX_SHOULDER]->AddChild(m_apFrames[ARCHER_INDEX_RIGHTARMBONE]);
        m_apFrames[ARCHER_INDEX_LEFTARMBONE]->AddChild(m_apFrames[ARCHER_INDEX_LEFTARM]);
        m_apFrames[ARCHER_INDEX_RIGHTARMBONE]->AddChild(m_apFrames[ARCHER_INDEX_RIGHTARM]);
        m_apFrames[ARCHER_INDEX_LEFTARM]->AddChild(m_apFrames[ARCHER_INDEX_LEFTHANDBONE]);
        m_apFrames[ARCHER_INDEX_RIGHTARM]->AddChild(m_apFrames[ARCHER_INDEX_RIGHTHANDBONE]);
        m_apFrames[ARCHER_INDEX_LEFTHANDBONE]->AddChild(m_apFrames[ARCHER_INDEX_LEFTHAND]);
        m_apFrames[ARCHER_INDEX_RIGHTHANDBONE]->AddChild(m_apFrames[ARCHER_INDEX_RIGHTHAND]);
        m_apFrames[ARCHER_INDEX_RIGHTHAND]->AddChild(m_apFrames[ARCHER_INDEX_BOW]);
        m_apFrames[ARCHER_INDEX_LEFTHAND]->AddChild(m_apFrames[ARCHER_INDEX_ARROW]);
        
    }
    
    m_bLoaded = true;
    
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::_InitBowInfo(const BowInfo &bowInfo)
{
    m_pSprBow->SetSpace(m_frameInfo[ARCHER_INDEX_BOW]._ptAnchor.y - (m_frameInfo[ARCHER_INDEX_BOW]._ptSize.y - (bowInfo._ptRight.y + bowInfo._ptLeft.y) * 0.5f));
    m_pSprBow->SetLinePara(ccpAdjustRes(bowInfo._ptRight.x, bowInfo._ptRight.y), ccpAdjustRes(bowInfo._ptLeft.x, bowInfo._ptLeft.y));
	m_pSprBow->SetMaxPower(bowInfo._ptRight.x - bowInfo._ptLeft.x);
    
    
    // 手臂长度
    m_armLength  = m_frameInfo[ARCHER_INDEX_RIGHTHANDBONE]._ptPos.y - m_frameInfo[ARCHER_INDEX_RIGHTARM]._ptAnchor.y;
    // 弓箭的最大力度，即弓弦的长度
}

void CArcher::_InitAABB(const AABBInfo &aabbInfo)
{
    m_aabbHeadOrg = aabbInfo._aabbHead;
    m_aabbBodyOrg = aabbInfo._aabbBody;
    m_aabbFootOrg = aabbInfo._aabbFoot;
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_SetLocalAnimation(bool bFlip, bool bFirst)
{
    float maxHeadAngle = 60;
    float minHeadAngle = -45;
    
    // 这个还得设置。。。
    
    m_maxAngle = 75;
    m_minAngle = -75;
    
    
    float rotAdd = 0;
    
    if(bFlip)
    {
        rotAdd += 180;
    }
    
    
    // 拉弦的手与弓弦中点的距离
    float space = m_armLength * 2 - m_pSprBow->GetSpace();
    
    ArcherAnimInfo  animInfo[ARCHER_INDEX_MAX];
    
    animInfo[ARCHER_INDEX_HEAD]._rotKeyCount    = 2;
    animInfo[ARCHER_INDEX_HEAD]._bUseLocalTime = true;
    
    for(int i=0; i<animInfo[ARCHER_INDEX_HEAD]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_HEAD]._rotKeys[i]    = minHeadAngle + (maxHeadAngle - minHeadAngle) * i;
        animInfo[ARCHER_INDEX_HEAD]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_HEAD]._rotKeyCount-1);
    }
    
    
    // 左臂骨头动作 旋转
    animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_LEFTARMBONE]._bUseLocalTime = true;
    for(int i=0; i<animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeys[i] = 1 + 178 * i + rotAdd;
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount-1);
    }
    
    
    // 右臂动作 平移
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._bUseLocalTime = true;
    for(int i=0; i<animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeys[i] = 1 + 178 * i + rotAdd;
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount-1);
    }
    
    if(space < 0)
    {
        animInfo[ARCHER_INDEX_LEFTHAND]._posKeyCount     = 2;
        animInfo[ARCHER_INDEX_LEFTHAND]._bUseLocalTime = true;
        float leftTime[2] =
        {
            0,
            1.0f
        };
        
        Vector3D leftHandPos[2] = 
        {
            Vector3D(0, 0, 0),
            Vector3D(0, (m_pSprBow->GetMaxPower() *0.5f - space), 0),
            
        };
        for(int i=0; i<animInfo[ARCHER_INDEX_LEFTHAND]._posKeyCount; i++)
        {
            animInfo[ARCHER_INDEX_LEFTHAND]._posKeys[i] = leftHandPos[i];
            animInfo[ARCHER_INDEX_LEFTHAND]._posTimes[i]   = leftTime[i];
        }
    }
    else
    {
        // 左手动作
        animInfo[ARCHER_INDEX_LEFTHAND]._posKeyCount     = 3;
        animInfo[ARCHER_INDEX_LEFTHAND]._bUseLocalTime = true;
        float leftTime[3] =
        {
            0,
            space / (m_pSprBow->GetMaxPower() * 0.5f),
            1.0f
        };
        
        
        
        Vector3D leftHandPos[3] = 
        {
            Vector3D(0, 0, 0),
            Vector3D(0, 0, 0),
            Vector3D(0, (m_pSprBow->GetMaxPower() *0.5f - space), 0),
            
        };
        for(int i=0; i<animInfo[ARCHER_INDEX_LEFTHAND]._posKeyCount; i++)
        {
            animInfo[ARCHER_INDEX_LEFTHAND]._posKeys[i] = leftHandPos[i];
            animInfo[ARCHER_INDEX_LEFTHAND]._posTimes[i]   = leftTime[i];
        }
    }
    
    
    
    if(space > 0)
    {
        // 左臂动作
        animInfo[ARCHER_INDEX_LEFTARM]._posKeyCount     = 3;
        animInfo[ARCHER_INDEX_LEFTARM]._bUseLocalTime = true;
        
        float leftTime[3] =
        {
            0,
            space / (m_pSprBow->GetMaxPower() * 0.5f),
            1.0f
        };
        
        Vector3D leftArmPos[3] = 
        {
            Vector3D(0, -space, 0),
            Vector3D(0, 0, 0),
            Vector3D(0, 0, 0),
            
        };
        for(int i=0; i<animInfo[ARCHER_INDEX_LEFTARM]._posKeyCount; i++)
        {
            animInfo[ARCHER_INDEX_LEFTARM]._posKeys[i]  = leftArmPos[i];
            animInfo[ARCHER_INDEX_LEFTARM]._posTimes[i] = leftTime[i];
        }
    }
    
    
    if(bFirst)
    {
        _AddAnimation(animInfo, "shoot", 500);
    }
    else
    {
        _ChangeAnimation(animInfo, "shoot");
    }
    
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_SetHurtAnimation(bool bFlip, bool bFirst)
{
    ArcherAnimInfo  animInfo[ARCHER_INDEX_MAX];
    
    animInfo[ARCHER_INDEX_HEAD]._rotKeyCount    = 3;
    animInfo[ARCHER_INDEX_HEAD]._bUseLocalTime = false;
    
    int s = 1;
    if(bFlip)
    {
        s = -1;
    }
    
    float headRot[3] = 
    {
        0,
        30 * s,
        0
    };
    for(int i=0; i<animInfo[ARCHER_INDEX_HEAD]._rotKeyCount; i++)
    {
       
        animInfo[ARCHER_INDEX_HEAD]._rotKeys[i]    = headRot[i];
       
        animInfo[ARCHER_INDEX_HEAD]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_HEAD]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_BODY]._rotKeyCount = 3;
    animInfo[ARCHER_INDEX_BODY]._bUseLocalTime = false;
    
    float bodyRot[3] = 
    {
        0,
        15 * s,
        0
    };
    for(int i=0; i<animInfo[ARCHER_INDEX_BODY]._rotKeyCount; i++)
    {
        
        animInfo[ARCHER_INDEX_BODY]._rotKeys[i]    = bodyRot[i];
        
        animInfo[ARCHER_INDEX_BODY]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_BODY]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_LEFTARMBONE]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeys[i] = 165 * s;
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_LEFTHAND]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_LEFTHAND]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_LEFTHAND]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_LEFTHAND]._rotKeys[i] = -90*s;
        animInfo[ARCHER_INDEX_LEFTHAND]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_LEFTHAND]._rotKeyCount-1);
    }
     
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeys[i] = 30*s;
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_RIGHTHAND]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeys[i] =  90 *s;
        animInfo[ARCHER_INDEX_RIGHTHAND]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeyCount-1);
    }

    if(bFirst)
    {
        _AddAnimation(animInfo, "hurt", 300);
    }
    else
    {
        _ChangeAnimation(animInfo,  "hurt");
    }
    
    
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_SetHurtBodyAnimation(bool bFlip, bool bFirst)
{
    ArcherAnimInfo  animInfo[ARCHER_INDEX_MAX];
    
    animInfo[ARCHER_INDEX_HEAD]._rotKeyCount    = 3;
    animInfo[ARCHER_INDEX_HEAD]._bUseLocalTime = false;
    
    int s = 1;
    if(bFlip)
    {
        s = -1;
    }
    
    float headRot[3] = 
    {
        0,
        -60 * s,
        0
    };
    for(int i=0; i<animInfo[ARCHER_INDEX_HEAD]._rotKeyCount; i++)
    {
        
        animInfo[ARCHER_INDEX_HEAD]._rotKeys[i]    = headRot[i];
        
        animInfo[ARCHER_INDEX_HEAD]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_HEAD]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_BODY]._rotKeyCount = 3;
    animInfo[ARCHER_INDEX_BODY]._bUseLocalTime = false;
    
    float bodyRot[3] = 
    {
        0,
        30 * s,
        0
    };
    for(int i=0; i<animInfo[ARCHER_INDEX_BODY]._rotKeyCount; i++)
    {
        
        animInfo[ARCHER_INDEX_BODY]._rotKeys[i]    = bodyRot[i];
        
        animInfo[ARCHER_INDEX_BODY]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_BODY]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_LEFTARMBONE]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeys[i] = 165 * s;
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_LEFTHAND]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_LEFTHAND]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_LEFTHAND]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_LEFTHAND]._rotKeys[i] = -90*s;
        animInfo[ARCHER_INDEX_LEFTHAND]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_LEFTHAND]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeys[i] = 30*s;
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount-1);
    }
    
    animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeyCount     = 2;
    animInfo[ARCHER_INDEX_RIGHTHAND]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeys[i] =  90 *s;
        animInfo[ARCHER_INDEX_RIGHTHAND]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_RIGHTHAND]._rotKeyCount-1);
    }
    
    if(bFirst)
    {
        _AddAnimation(animInfo, "hurtBody", 300);
    }
    else
    {
        _ChangeAnimation(animInfo,  "hurtBody");
    }
    
    
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_SetWalkAnimation(bool bFlip, bool bFirst)
{
    
    ArcherAnimInfo  animInfo[ARCHER_INDEX_MAX];
    
    animInfo[ARCHER_INDEX_HEAD]._rotKeyCount    = 3;
    animInfo[ARCHER_INDEX_HEAD]._bUseLocalTime = false;
    
    int s = 1;
    if(bFlip)
    {
        s = -1;
    }
    
    float headRot[3] = 
    {
        0,
        -10 * s,
        0
    };
    for(int i=0; i<animInfo[ARCHER_INDEX_HEAD]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_HEAD]._rotKeys[i]    = headRot[i];
        animInfo[ARCHER_INDEX_HEAD]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_HEAD]._rotKeyCount-1);
    }
    
    
    
    float bodyRot[3] = 
    {
        -10 * s,
        -10 * s,
        -10 * s
    };
    
    animInfo[ARCHER_INDEX_BODY]._rotKeyCount = 3;
    animInfo[ARCHER_INDEX_BODY]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_BODY]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_BODY]._rotKeys[i]    = bodyRot[i];
        animInfo[ARCHER_INDEX_BODY]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_BODY]._rotKeyCount-1);
    }
    
    Vector3D bodyPos[3] =
    {
        Vector3D(0, 0, 0),
        Vector3D(0, 5, 0),
        Vector3D(0, 0, 0),
    };
    
    animInfo[ARCHER_INDEX_BODY]._posKeyCount = 3;
    animInfo[ARCHER_INDEX_BODY]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_BODY]._posKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_BODY]._posKeys[i]  = bodyPos[i];
        animInfo[ARCHER_INDEX_BODY]._posTimes[i] = (float)i / (animInfo[ARCHER_INDEX_BODY]._posKeyCount-1);
    }
    
    float rotAdd = 0;
    
    if(bFlip)
    {
        rotAdd = 180;
    }
    float armRot[3] = 
    {
        90 + rotAdd,
        90 + 10 * s + rotAdd,
        90 + rotAdd
    };
    
    animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount     = 3;
    animInfo[ARCHER_INDEX_LEFTARMBONE]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeys[i] = armRot[i];
        animInfo[ARCHER_INDEX_LEFTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_LEFTARMBONE]._rotKeyCount-1);
    }
    
       
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount     = 3;
    animInfo[ARCHER_INDEX_RIGHTARMBONE]._bUseLocalTime = false;
    for(int i=0; i<animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount; i++)
    {
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeys[i] = armRot[i];
        animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotTimes[i]   = (float)i / (animInfo[ARCHER_INDEX_RIGHTARMBONE]._rotKeyCount-1);
    }
    
    if(bFirst)
    {
        _AddAnimation(animInfo, "walk", 300);
    }
    else
    {
        _ChangeAnimation(animInfo,  "walk");
    }
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_AddAnimation(ArcherAnimInfo animInfo[ARCHER_INDEX_MAX], const char *szAnimName, float length)
{
    AnimationSet *pCurAnimSet = NULL;
    
    AnimationSet *pParentSet = m_pAnimSet;
    if(NULL == pParentSet)
    {
        m_pAnimSet = new AnimationSet;	
        pCurAnimSet = m_pAnimSet;
    }
    else
    {
        pCurAnimSet = new AnimationSet;
        
        while (NULL != pParentSet->_pNext) 
        {
            pParentSet = pParentSet->_pNext;
        }
        
        pParentSet->_pNext = pCurAnimSet;
    }
    
    
	pCurAnimSet->_pName = new char[ANIMATIONSET_NAME_MAX];
	pCurAnimSet->_length = length;
	strcpy(pCurAnimSet->_pName, szAnimName);
    
	ArcherAnimInfo  *pCurAnimInfo  = animInfo;
    
	Animation *pAnims[ARCHER_INDEX_MAX];
	Animation *pAnimLast = NULL;
    
    for(int i=0; i<ARCHER_INDEX_MAX; i++)
    {
        pAnims[i] = new Animation;
		pAnims[i]->_pFrame = m_apFrames[i];
        
		if(pCurAnimInfo->_rotKeyCount > 0)
		{
            pAnims[i]->_bUseRotTime = pCurAnimInfo->_bUseLocalTime;
			pAnims[i]->_nRotateKeys = pCurAnimInfo->_rotKeyCount;
			pAnims[i]->_pRotateKeys = new RotateKey[pAnims[i]->_nRotateKeys];
			for(unsigned long j=0; j<pAnims[i]->_nRotateKeys; j++)
			{
				Quaternion q;
                
				q.SetRotateZ(CC_DEGREES_TO_RADIANS(pCurAnimInfo->_rotKeys[j]));
				pAnims[i]->_pRotateKeys[j]._quaternion = q;
				pAnims[i]->_pRotateKeys[j]._time = pCurAnimSet->_length * pCurAnimInfo->_rotTimes[j];
			}
		}
        
		if(pCurAnimInfo->_posKeyCount > 0)
		{
			pAnims[i]->_bUsePosTime = pCurAnimInfo->_bUseLocalTime;
			pAnims[i]->_nPositionKeys = pCurAnimInfo->_posKeyCount;
			pAnims[i]->_pPositionKeys = new PositionKey[pAnims[i]->_nPositionKeys];
            
			for(unsigned long j=0; j<pAnims[i]->_nPositionKeys; j++)
			{
				pAnims[i]->_pPositionKeys[j]._pos = Vector3D(pCurAnimInfo->_posKeys[j].x, pCurAnimInfo->_posKeys[j].y, 0);
				pAnims[i]->_pPositionKeys[j]._time = pCurAnimSet->_length * pCurAnimInfo->_posTimes[j];;
				if(j > 0)
				{
					pAnims[i]->_pPositionKeys[j-1]._posInterpolation = 
                    (pAnims[i]->_pPositionKeys[j]._pos - pAnims[i]->_pPositionKeys[j-1]._pos) / (pAnims[i]->_pPositionKeys[j]._time - pAnims[i]->_pPositionKeys[j-1]._time);
				}
			}
		}
        
		if(NULL == pAnimLast)
		{
			pCurAnimSet->_pAnim = pAnims[i];
			pAnimLast= pAnims[i];
		}
		else
		{
			pAnimLast->_pNext = pAnims[i];
			pAnimLast = pAnims[i];
		}
        
        pCurAnimInfo++;
    }
}

//-------------------------------------------------------------------------------------------------------------------/
void CArcher::_ChangeAnimation(ArcherAnimInfo *animInfo, const char *szAnimName)
{
    AnimationSet *pCurAnimSet = GetAnimSet(szAnimName);
    
    if(NULL == pCurAnimSet)
    {
        return;
    }
    
	ArcherAnimInfo  *pCurAnimInfo  = animInfo;
    
    
    Animation *pCurAnim = pCurAnimSet->_pAnim;
    
    for(int i=0; i<ARCHER_INDEX_MAX; i++)
    {
		if(pCurAnimInfo->_rotKeyCount > 0)
		{
            pCurAnim->_bUseRotTime = pCurAnimInfo->_bUseLocalTime;
			pCurAnim->_nRotateKeys = pCurAnimInfo->_rotKeyCount;
			for(unsigned long j=0; j<pCurAnim->_nRotateKeys; j++)
			{
				Quaternion q;
                
				q.SetRotateZ(CC_DEGREES_TO_RADIANS(pCurAnimInfo->_rotKeys[j]));
				pCurAnim->_pRotateKeys[j]._quaternion = q;
				pCurAnim->_pRotateKeys[j]._time = pCurAnimSet->_length * pCurAnimInfo->_rotTimes[j];
			}
            
		}
        
		if(pCurAnimInfo->_posKeyCount > 0)
		{
			pCurAnim->_bUsePosTime = pCurAnimInfo->_bUseLocalTime;
			pCurAnim->_nPositionKeys = pCurAnimInfo->_posKeyCount;
            
			for(unsigned long j=0; j<pCurAnim->_nPositionKeys; j++)
			{
				pCurAnim->_pPositionKeys[j]._pos = Vector3D(pCurAnimInfo->_posKeys[j].x, pCurAnimInfo->_posKeys[j].y, 0);
				pCurAnim->_pPositionKeys[j]._time = pCurAnimSet->_length * pCurAnimInfo->_posTimes[j];;
				if(j > 0)
				{
					pCurAnim->_pPositionKeys[j-1]._posInterpolation = 
                    (pCurAnim->_pPositionKeys[j]._pos - pCurAnim->_pPositionKeys[j-1]._pos) / (pCurAnim->_pPositionKeys[j]._time - pCurAnim->_pPositionKeys[j-1]._time);
				}
			}
		}
        
        pCurAnim = pCurAnim->_pNext;
        
        pCurAnimInfo++;
    }
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::_InitActions()
{
    m_pActHurt = CCSequence::actions(CCShow::action(), CAnimationHelper::BuildAnimate(1, 6, "hurt%d.png", 0.05f), CCHide::action(), NULL);
    m_pActHurt->retain();
    
    m_pActBlood = CCSequence::actions(CCShow::action(), CAnimationHelper::BuildAnimate(1, 7, "blood%d.png", 0.05f), CCHide::action(), NULL);
    m_pActBlood->retain();
    
    m_pSprHurt = CCSprite::spriteWithSpriteFrameName("hurt1.png");
    m_pSprBlood = CCSprite::spriteWithSpriteFrameName("blood1.png");
    addChild(m_pSprHurt, 100);
    addChild(m_pSprBlood, 101);
    m_pSprHurt->setIsVisible(false);
    m_pSprBlood->setIsVisible(false);
    
    /*
    m_pSprPoint[0] = CCSprite::spriteWithFile("Objects/point.png");
    m_pSprPoint[1] = CCSprite::spriteWithFile("Objects/point.png");
    
    getParent()->addChild(m_pSprPoint[0], 100);
    getParent()->addChild(m_pSprPoint[1], 100);
     */
   
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::_FlipActions(bool bFlip)
{
    if(NULL != m_pSprBlood)
    {
        m_pSprBlood->setFlipX(bFlip);
    }
    if(NULL != m_pSprHurt)
    {
        m_pSprHurt->setFlipX(bFlip);
    }
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::SetFlip(bool bFlip)
{
    if(m_bFlip == bFlip)
    {
        return;
    }
    
    m_bFlip = bFlip;
    
    ArcherFrameInfo info[ARCHER_INDEX_MAX];
    memcpy(&info, &m_frameInfo, sizeof(info));
    
    float curAngle = GetCurAngle();
    
    if(curAngle < 0)
    {
        curAngle = -180 - curAngle;
    }
    else
    {
        curAngle = 180 - curAngle;
    }
    
    
    if(bFlip)
    {
        // 非翻转到翻转 右转左
        
        info[ARCHER_INDEX_BODY]._ptAnchor.x  = info[ARCHER_INDEX_BODY]._ptSize.x - info[ARCHER_INDEX_BODY]._ptAnchor.x;
        
        //info[ARCHER_INDEX_NECK]._ptAnchorParent = info[ARCHER_INDEX_BODY]._ptAnchor;
        
        //info[ARCHER_INDEX_NECK]._ptPos.x     = info[ARCHER_INDEX_BODY]._ptSize.x - info[ARCHER_INDEX_NECK]._ptPos.x;
        info[ARCHER_INDEX_HEAD]._ptAnchor.x  = info[ARCHER_INDEX_HEAD]._ptSize.x - info[ARCHER_INDEX_HEAD]._ptAnchor.x;
        //info[ARCHER_INDEX_SHOULDER]._ptAnchorParent = info[ARCHER_INDEX_BODY]._ptAnchor;
        //info[ARCHER_INDEX_SHOULDER]._ptPos.x = info[ARCHER_INDEX_BODY]._ptSize .x - info[ARCHER_INDEX_SHOULDER]._ptPos.x;
         
    }
    
    for(map<Frame *, int>::iterator iter = m_mapFrameAttached.begin(); iter != m_mapFrameAttached.end(); iter++)
    {
        Frame *pCurFrame = (iter->first);
        
        if(NULL != pCurFrame->_pSprBone)
        {
            Vector3D vec = Vector3D(0, 0, 0) * pCurFrame->_matOriginal;
            float p = 3.1415926 - atan2(pCurFrame->_matOriginal.m21, pCurFrame->_matOriginal.m22) ;
            Quaternion qRot;
            Matrix4X3  mRot;
            Matrix4X3  mOrg;
            mOrg.Reset();
            mOrg.SetTranslation(vec);
            qRot.SetRotateZ(p);
            mRot.FromQuaternion(qRot);
            pCurFrame->_matOriginal  = mRot * mOrg;
        }
    }
    

    
    
    _InitFrames(info, bFlip, false);
    UpdateAABB();
    _SetHurtAnimation(bFlip, false);
    _SetLocalAnimation(bFlip, false);
    _SetWalkAnimation(bFlip, false);
    _SetHurtBodyAnimation(bFlip, false);
    SetCurRotate(curAngle);
    
    
    float resScale = CGameGlobal::GetInstance()->m_resScale;
    if(NULL != m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone)
    {
        if(m_bFlip)
        {
            m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->setAnchorPoint(ccp((float)(m_curArrowInfo._arrowWidth) / (m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->getContentSize().width/ resScale), 0.5));
        }
        else
        {
            m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->setAnchorPoint(ccp((float)(m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->getContentSize().width / resScale - m_curArrowInfo._arrowWidth) / (m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->getContentSize().width / resScale), 0.5));

        }
    }
    
    
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::AddTarget(CArcherBase *pTarget)
{
    list<CArcherBase *>::iterator iterFind = find(m_listTarget.begin(), m_listTarget.end(), pTarget);
    
    if(iterFind == m_listTarget.end())
    {
        m_listTarget.push_back(pTarget);
    }
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::AttachFrame(int parentIndex, cocos2d::CCPoint pt, float angle, cocos2d::CCSprite *pSpr)
{
    if(parentIndex >= ARCHER_INDEX_MAX)
    {
        return;
    }
    
    
    if(m_bFlip)
    {
        // Y轴被旋转了
        angle = -angle;
    }
    
    Frame *pNewFrame = new Frame;
    pNewFrame->_pSprBone = pSpr;
    addChild(pSpr, 0);
    
    Matrix4X3 mOrg;
    Quaternion qRot;
    Matrix4X3 mRot;
    mOrg.Reset();
    // X置为0 ，为了美观，不用ENDTIME++了
    mOrg.SetupTranslation(Vector3D(pt.x, pt.y, 0));
    qRot.SetRotateZ(CC_DEGREES_TO_RADIANS(angle));
    mRot.FromQuaternion(qRot);
    pNewFrame->_matOriginal  = mRot * mOrg;
    
    Frame *pParentFrame = m_apFrames[parentIndex];
    pParentFrame->AddChild(pNewFrame);
    
    // 留着以后各种操作用
    m_mapFrameAttached.insert(make_pair(pNewFrame, parentIndex));
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::SetPos(const cocos2d::CCPoint &newPosition)
{
    CArcherBase::SetPos(MyPoint(newPosition.x, newPosition.y));
    
    setPosition(CGameGlobal::GetInstance()->AdjustResPos(newPosition));
    
    /*
    m_pSprPoint[0]->setPosition(CGameGlobal::GetInstance()->AdjustResPos(m_aabbFoot._ptRightBottom));
    m_pSprPoint[1]->setPosition(CGameGlobal::GetInstance()->AdjustResPos(m_aabbHead._ptLeftUp));
    */
}

//--------------------------------------------------------------------------------------------------------------------
void CArcher::Hitted(HitPositon pos, MyPoint ptHurt)
{
    int lastHp = m_hp;
    CArcherBase::Hitted(pos, MyPoint(ptHurt.x, ptHurt.y));
    
    int hurtHp = m_hp = lastHp;
    
    switch (pos) 
    {
        case ARCHER_HIT_BODY:
        {
            hurtHp = -30;
        }
            break;
            
        case ARCHER_HIT_HEAD:
        {
            hurtHp = -45;
        }
            break;
            
        case ARCHER_HIT_FOOT:
        {
            hurtHp = -25;
        }
            break;
        default:
            break;
    }
    

    if(hurtHp < 0)
    {
        m_hurtInfo._hp = hurtHp;
        m_hurtInfo._type = pos;
        m_hurtInfo._ptPos = ccp(ptHurt.x, ptHurt.y);
    }
    else
    {
        m_hurtInfo._type = -1;
    }
    
    
    // 打中效果
}

//--------------------------------------------------------------------------------------------------------------------/
bool CArcher::CheckHurt(const ArrowInfo &arrowInfo, cocos2d::CCSprite *pArrowFlying)
{
    if(m_hurtInfo._type == -1)
    {
        return false;
    }
    
    // 喷血效果
    m_pSprHurt->setPosition(convertToNodeSpace(getParent()->convertToWorldSpace(pArrowFlying->getPosition())));
    m_pSprHurt->setIsVisible(true);
    m_pSprHurt->runAction(m_pActHurt);

    m_pSprBlood->setPosition(convertToNodeSpace(getParent()->convertToWorldSpace(pArrowFlying->getPosition())));
    m_pSprBlood->setIsVisible(true);
    m_pSprBlood->runAction(m_pActBlood);
    
    
    // 获取受伤动作信息
    AnimationSet *pHurtSet = NULL;
    
    // 造一把插在身上的箭
    CCSprite *pSprArrow;
    if(arrowInfo._bUseFrame)
    {
        pSprArrow = CCSprite::spriteWithSpriteFrameName(arrowInfo._fileName);
        
    }
    else
    {
        pSprArrow= CCSprite::spriteWithFile(arrowInfo._fileName);
    }
    
    pSprArrow->setAnchorPoint(ccp(1, 0.5));
    
    int index = -1;
    if(m_hurtInfo._type == ARCHER_HIT_HEAD)
    {
        SetAnimation("hurt", -1);
        pHurtSet = GetAnimSet("hurt");
    
        index = ARCHER_INDEX_HEAD;

		SimpleAudioEngine::sharedEngine()->playEffect("Music/hurtHead.mp3");
        
    }
    else
    {
        SetAnimation("hurtBody", -1);
        pHurtSet = GetAnimSet("hurtBody");
               
        index = ARCHER_INDEX_BODY;
        if(m_hurtInfo._type == ARCHER_HIT_FOOT)
        {
            m_bCanMove = false;
        }

		SimpleAudioEngine::sharedEngine()->playEffect("Music/hurtBody.mp3");
    }
    
    if(index != -1)
    {
        float arrowRad = CC_DEGREES_TO_RADIANS(-pArrowFlying->getRotation());
        
            
        CCPoint ptAttach = pArrowFlying->getPosition();
        
        float percent = (6 + rand() % 3) * 0.1f;
        ptAttach.x += cos(arrowRad) * arrowInfo._arrowWidth * percent * CGameGlobal::GetInstance()->m_resScale;
        ptAttach.y += sin(arrowRad) * arrowInfo._arrowWidth * percent * CGameGlobal::GetInstance()->m_resScale;
        ptAttach = CGameGlobal::GetInstance()->RestoreResToLogicPos(m_apFrames[index]->_pSprBone->convertToNodeSpaceAR(getParent()->convertToWorldSpace(ptAttach)));
        
        if(m_bFlip)
        {
            ptAttach.x =  - ptAttach.x;
        }
        
        float angle = -(pArrowFlying->getRotation()) + m_apFrames[index]->_pSprBone->getRotation();
        AttachFrame(index, ptAttach, angle , pSprArrow);
    }
   
    
    // 别握着弓弦了
    SetUpdateBow(false);
     
    // 受伤结束恢复原状
    if(NULL != pHurtSet)
    {
        m_pSprHurt->runAction(CCSequence::actionOneTwo(
                              CCDelayTime::actionWithDuration((float)(pHurtSet->_length) / 1000.0f), 
                              CCCallFunc::actionWithTarget(this, callfunc_selector(CArcher::OnHurtEnd))));
    }
   
    
    m_hurtInfo._type = -1;
    
    return true;
}

bool CArcher::Hurt(int hurtPos, const ArrowInfo &arrowInfo, cocos2d::CCSprite *pArrowFlying)
{
    if(hurtPos == 0)
    {
        m_hurtInfo._type = -1;
        
        return false;
    }
    else if(hurtPos == 1)
    {
        m_hurtInfo._type = ARCHER_HIT_HEAD;
    }
    else if(hurtPos == 2)
    {
        m_hurtInfo._type = ARCHER_HIT_BODY;
    }
    else if(hurtPos == 3)
    {
        m_hurtInfo._type = ARCHER_HIT_FOOT;
    }
    else
    {
        return false;
    }
    
    if(NULL == pArrowFlying)
    {
        return false;
    }
    
    pArrowFlying->setIsVisible(false);

    return CheckHurt(arrowInfo, pArrowFlying);
}
//--------------------------------------------------------------------------------------------------------------------/
void CArcher::OnHurtEnd()
{
    SetPrepareShoot();
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::MoveLeft()
{

    if(!m_bFlip)
    {
        SetFlip(true);
    }
    CArcherBase::SetPos(MyPoint(m_ptPos.x - 1, m_ptPos.y));
    
    if(!m_bWalking)
    {
        SetAnimation("walk", -1);
        m_bWalking = true;
    }
}

void CArcher::MoveTo(cocos2d::CCPoint pt)
{
    
}
//--------------------------------------------------------------------------------------------------------------------/
void CArcher::MoveRight()
{
    if(m_bFlip)
    {
        SetFlip(false);
    }
    
    SetPos(ccp(m_ptPos.x + 1, m_ptPos.y));
    
    if(!m_bWalking)
    {
        SetAnimation("walk", -1);
        m_bWalking = true;
    }
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::Dead(int groundHeight)
{
    m_bLoaded = false;
    
    // 带有图片的关节索引
    int index[7] = 
    {
        ARCHER_INDEX_BOW,
        ARCHER_INDEX_HEAD, 
        ARCHER_INDEX_LEFTARM, 
        ARCHER_INDEX_RIGHTARM, 
        ARCHER_INDEX_LEFTHAND, 
        ARCHER_INDEX_RIGHTHAND,
        ARCHER_INDEX_BODY,
    };
    
    int s = 1;      // 正负号
    
    if(!m_bFlip)
    {
        s = -1;
    }
    
    // 每个部位最终的角度
    float angle[7] = 
    {
        0,
        90 * s,
        90 * s,
        90 * s,
        90 * s,
        90 * s,
        90 * s,
    };
    
    // 各个关节下落高度
    float height[7] = 
    {
        0,
        10,
        5,
        5,
        5,
        5,
        10,
    };
    
	if(NULL != m_pCurArrow)
	{
		m_pCurArrow->GetSprite()->setIsVisible(false);
	}

    float resScale = CGameGlobal::GetInstance()->m_resScale;
    
    // 所有的关节和插在身上的箭全都落下
    for(int i=0; i<7; i++)
    {
        m_apFrames[index[i]]->_pSprBone->runAction(CCRotateTo::actionWithDuration(0.5f, angle[i]));
        m_apFrames[index[i]]->_pSprBone->runAction(CCMoveTo::actionWithDuration(0.5f, ccp(m_apFrames[index[i]]->_pSprBone->getPosition().x , height[i])));
    }
    
	if(NULL != m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone)
	{
		m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->setIsVisible(false);
	}
    for(map<Frame *, int>::iterator iter = m_mapFrameAttached.begin(); iter != m_mapFrameAttached.end(); iter++)
    {
        Frame *pFrame = (iter->first);
        
        pFrame->_pSprBone->runAction(CCRotateTo::actionWithDuration(0.5f, 0));
        pFrame->_pSprBone->runAction(CCMoveTo::actionWithDuration(0.5f, ccp(pFrame->_pSprBone->getPosition().x , 0)));
        
        
    }
    
    CCPoint ptChar = getPosition();
    
    // 身体下沉
    runAction(CCMoveTo::actionWithDuration(1.0f, ccp(ptChar.x, groundHeight * resScale)));
    
    
    // 灵魂
    ptChar.y += 100 * resScale;
    CCSprite *pSprSoul;
    if(m_type == 1)
    {
        pSprSoul = CCSprite::spriteWithSpriteFrameName("soulArcher1.png");
    }
    else
    {
        pSprSoul = CCSprite::spriteWithSpriteFrameName("soulArcher2.png");
    }
    
    pSprSoul->setPosition(ptChar);
    getParent()->addChild(pSprSoul);
    pSprSoul->setFlipX(m_bFlip);
    pSprSoul->runAction(CCRepeatForever::actionWithAction(
                                                            (CCActionInterval *)CCSequence::actions(
                                                                                                    CCMoveTo::actionWithDuration(2.0f, ccp(ptChar.x, ptChar.y + 20 * resScale)),
                                                                                                    CCDelayTime::actionWithDuration(0.3f),
                                                                                                    CCMoveTo::actionWithDuration(2.0f, ccp(ptChar.x, ptChar.y - 20 * resScale)),
                                                                                                    CCDelayTime::actionWithDuration(0.3f),
                                                                                                    NULL)));
    
    
    // 鬼火
    s = 1;
    for(int i=0; i<2; i++)
    {
        s*=-1;
        
        CCSprite *pSprSoulFire = CCSprite::spriteWithSpriteFrameName("soulFire.png");
        pSprSoulFire->setPosition(ccp(ptChar.x + 40*s*resScale, ptChar.y));
        getParent()->addChild(pSprSoulFire);
        pSprSoulFire->runAction(CCRepeatForever::actionWithAction(
                                                                       (CCActionInterval *)CCSequence::actions(
                                                                                                               CCMoveTo::actionWithDuration(2.0f, ccp(ptChar.x+40*s*resScale, ptChar.y + 10 * resScale)),
                                                                                                               CCDelayTime::actionWithDuration(0.3f),
                                                                                                               CCMoveTo::actionWithDuration(2.0f, ccp(ptChar.x+40*s*resScale, ptChar.y - 10 * resScale)),
                                                                                                               CCDelayTime::actionWithDuration(0.3f),
                                                                                                               NULL)));
        
        pSprSoulFire->runAction(CCRepeatForever::actionWithAction(CCRotateBy::actionWithDuration(0.03f, s*5.0f)));
    }

	
    
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::SetPrepareShoot()
{
    SetAnimation("shoot", 0);
    SetUpdateBow(true);
}
//--------------------------------------------------------------------------------------------------------------------/
void CArcher::MoveStop()
{
    if(m_bWalking)
    {
        SetAnimation("shoot", -1);
        m_bWalking = false;
    }
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::SetCurRotate(float angle)
{
    m_lastAngle = angle;
    if(m_bFlip)
    {
        angle -= 90;
    }
    else
    {
        angle += 90;
    }
    
    if(angle < 0)
    {
        angle += 360;
        
    }
    
	if(NULL == m_pCurAnimSet)
	{
		return;
	}
    
    float minAngle = 0;
    
    if(m_bFlip)
    {
        minAngle = 180;
    }
    
	Animation *pAnim = m_pCurAnimSet->_pAnim;
    
	while(NULL != pAnim)
	{
		if(pAnim->_bUseRotTime)
		{
            pAnim->_curRotTime = (m_pCurAnimSet->_length * angle - minAngle)/ 180.0f;
        }
        
		pAnim = pAnim->_pNext;
	}
    
    
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::SetCurStrength(float s)
{
	if(NULL == m_pCurAnimSet)
	{
		return;
	}

	Animation *pAnim = m_pCurAnimSet->_pAnim;

	while(NULL != pAnim)
	{
		if(pAnim->_bUsePosTime)
		{
			
			pAnim->_curPosTime = m_pCurAnimSet->_length * s / m_pSprBow->GetMaxPower();
		
		}

		pAnim = pAnim->_pNext;
	}

	m_curPower = s;
}

//--------------------------------------------------------------------------------------------------------------------/
CArrow *CArcher::BeginTouches(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
	if(!pTouches||!pTouches->count() || !m_bValid)
	{
		return NULL;
	}

    /*
	if(NULL != m_pCurTouch)
	{
		return NULL;
	}
     */

	CCPoint ptDiff; // 触摸点与弓箭中心坐标差

	cocos2d::CCSetIterator iter;
	float dist = 0;
	for(iter = pTouches->begin(); iter != pTouches->end(); iter++)
	{
		CCTouch *pTouch = (CCTouch *)(*iter);

		CCPoint ptTouch = getParent()->convertToNodeSpace(convertToWorldSpace(convertTouchToNodeSpace(pTouch)));
		CCPoint ptBowCenter = getParent()->convertToNodeSpace(m_pSprBow->GetWorldCenterOrgPos());
		
		ptDiff = ccp(ptTouch.x - ptBowCenter.x, ptTouch.y - ptBowCenter.y);

		dist = ccpDistance(ptBowCenter, ptTouch);

		if(dist > 100 * CGameGlobal::GetInstance()->m_resScale)
		{
            //获取小于100的触摸位置
			continue;;
		}

		m_pCurTouch = pTouch;
        
        if(NULL == m_pCurArrow)
        {
            AddArrow();
            
        }
       
		break;
	}

	if(iter == pTouches->end())
	{
		return NULL;
	}

	return m_pCurArrow;

	
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::MoveTouches(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
	if(NULL == m_pCurTouch)
	{
		return;
	}


	CCPoint ptTouch = getParent()->convertToNodeSpace(convertToWorldSpace(convertTouchToNodeSpace(m_pCurTouch)));
	CCPoint ptBowCenter = getParent()->convertToNodeSpace(convertToWorldSpace(m_pSprBow->getPosition()));

    // 当前点-上一点
	CCPoint ptDiff = ccp(ptTouch.x - ptBowCenter.x, ptTouch.y - ptBowCenter.y);
	
     // 距离为触摸点与弓箭中点距离。
	float dist = ccpDistance(ptBowCenter, ptTouch) * CGameGlobal::GetInstance()->m_resolutionScale - m_pSprBow->GetSpace() - 100;
    // -180 ~ 180
	float curAngle  = CC_RADIANS_TO_DEGREES(atan2(-ptDiff.y, - ptDiff.x));


    float min = m_minAngle;
    float max = m_maxAngle;
    
    if(m_bFlip)
    {
        // 都变成正的
        min = m_minAngle - (90 + m_minAngle) * 2;
        max  = m_maxAngle + (90 - m_maxAngle) * 2;
    }
    
    bool bCanRot = true;
    bool bCanPower = true;
    
    if(m_bFlip)
    {
        if(curAngle > min && curAngle < max)
        {
            bCanRot = false;
            
        }
    }
    else
    {
        if(curAngle > max || curAngle < min)
        {
            
            bCanRot = false;
        }
    }
    
    CCPoint ptLine1 = getParent()->convertToNodeSpace(m_pSprBow->GetWorldDownPos());
    CCPoint ptLine2 = getParent()->convertToNodeSpace(m_pSprBow->GetWorldUpPos());
    
    if(m_bFlip)
    {
        // 人物向左侧，左侧无效
        if(PointLineRelation(MyPoint(ptLine1.x, ptLine1.y), MyPoint(ptLine2.x, ptLine2.y), MyPoint(ptTouch.x, ptTouch.y)) <= 0)
        {
            m_curPower = 0;
            return;
        }
    }
    else
    {
        // 人物向左侧，左侧无效
        if(PointLineRelation(MyPoint(ptLine1.x, ptLine1.y), MyPoint(ptLine2.x, ptLine2.y), MyPoint(ptTouch.x, ptTouch.y)) >= 0)
        {
            m_curPower = 0;
            return;
        }
    }
    
    
    if(dist > m_pSprBow->GetMaxPower() / 0.75)
	{
		dist = m_pSprBow->GetMaxPower() / 0.75;
	}
    else if(dist < 0)
    {
        dist = 0;
    }
    
    dist *= 0.75f;
    
    if(dist <= 0)
    {
        bCanRot = false;
    }
   
    float angleDiff = 1;
    
    if(abs(curAngle - m_lastAngle) < angleDiff)
    {
        curAngle = m_lastAngle;
    }
     
    if(bCanRot)
    {
        SetCurRotate(curAngle);
    }
    
    if(bCanPower)
    {
		if(abs(dist - m_curPower) > 1)
		{
			if(m_nSoundPreshoot == -1)
			{
				m_nSoundPreshoot = SimpleAudioEngine::sharedEngine()->playEffect("Music/preshoot.mp3");
				runAction(CCSequence::actionOneTwo(CCDelayTime::actionWithDuration(2.0f), CCCallFunc::actionWithTarget(this, callfunc_selector(CArcher::OnEffectPreShoot))));

			}
		}
        SetCurStrength(dist);
    }
  
    if(NULL != m_pCurArrow)
    {
         m_pCurArrow->Prepare(getParent()->convertToNodeSpace(GetLeftHandPos()), GetCurAngle());
    }
	

}

//--------------------------------------------------------------------------------------------------------------------/
bool CArcher::DisableTouches(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
    CCTouch *pCurTouch = (CCTouch *)pTouches->anyObject();
    
    if(pCurTouch != m_pCurTouch)
    {
        return false;
    }
    
    if(m_curPower <= 0)
    {
        m_pCurTouch = NULL;
        return false;
    }
    
    //Shoot();
    
	if(m_nSoundPreshoot != -1)
	{
		SimpleAudioEngine::sharedEngine()->stopEffect(m_nSoundPreshoot);
	}
    return true;
}

void CArcher::SetCurArrow(const ArrowInfo &info)
{
    memcpy(&m_curArrowInfo, &info, sizeof(ArrowInfo));
}

CArrow *CArcher::AddArrow()
{
    if(NULL != m_pCurArrow)
    {
        m_pCurArrow->Remove();
        delete m_pCurArrow;
    }
    
    m_pCurArrow = CArrow::CreateArrow(m_curArrowInfo, getParent(), getZOrder() + 1);
    m_pCurArrow->Prepare(getParent()->convertToNodeSpace(GetLeftHandPos()), GetCurAngle());
    m_pSprBow->SetIsTouched(true);
    m_pCurArrow->GetSprite()->setIsVisible(false);
    
  
    if(NULL != m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone)
    {
        m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->removeAllChildrenWithCleanup(true);
    }
    
    CCSprite *pSprArrow;
    if(m_curArrowInfo._bUseFrame)
    {
        pSprArrow = CCSprite::spriteWithSpriteFrameName(m_curArrowInfo._fileName);
    }
    else
    {
        pSprArrow = CCSprite::spriteWithFile(m_curArrowInfo._fileName);
    }
    
    
    pSprArrow->setFlipX(m_bFlip);
    
    float resScale = CGameGlobal::GetInstance()->m_resScale;
    m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone = pSprArrow;
	    pSprArrow->setAnchorPoint(ccp((float)(pSprArrow->getContentSize().width / resScale - m_curArrowInfo._arrowWidth) / (pSprArrow->getContentSize().width / resScale), 0.5));
    
    if(m_bFlip)
    {
        pSprArrow->setAnchorPoint(ccp((float)(m_curArrowInfo._arrowWidth) / (pSprArrow->getContentSize().width / resScale), 0.5));
    }
    
    addChild(pSprArrow, ARCHER_INDEX_ARROW);
    
    
    return m_pCurArrow;
}

CArrow *CArcher::Shoot(cocos2d::CCPoint ptHead, float angle, float power)
{
    if(NULL != m_pCurArrow)
    {
        m_pCurArrow->GetSprite()->setIsVisible(true);
        m_pCurArrow->Shoot(power, ptHead, angle, &m_listTarget);
    }
    
    CArrow *pArrowRet = m_pCurArrow;
    
    m_pCurTouch = NULL;
	SetCurRotate(m_lastAngle);
    m_lastPower = m_curPower;
	SetCurStrength(0);
    m_pCurArrow = NULL;
    if(NULL != m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone)
    {
         m_apFrames[ARCHER_INDEX_ARROW]->_pSprBone->setIsVisible(false);
    }
   
    m_pSprBow->SetIsTouched(false);
    
	SimpleAudioEngine::sharedEngine()->playEffect("Music/shoot.mp3");
    return pArrowRet;
}
//--------------------------------------------------------------------------------------------------------------------/
CArrow *CArcher::AutoShoot(float power, float angle ,float xMove, float yMove, bool bFlip)
{
    m_autoPower = power;
    m_autoAngle = angle;
    m_autoMoveX = xMove;
    m_autoMoveY = yMove;
    m_autoFlip  = bFlip;
    
    m_autoStep  = AUTO_STEP_MOVE;
    
    if(NULL == m_pCurArrow)
    {
        AddArrow();
        
    }
    
    return m_pCurArrow;
    
}

//--------------------------------------------------------------------------------------------------------------------/
bool CArcher::UpdateAutoShoot(cocos2d::ccTime dt)
{
    if(m_autoStep == AUTO_STEP_NONE)
    {
        return false;
    }
    static float localTimer = 0;
    
    localTimer += dt;
    
    if(localTimer < Archer_AUTOSHOOT_DELAY)
    {
        return true;
    }
    
    localTimer = 0;
    
    bool bFinish = false;
    
    switch (m_autoStep) {
        case AUTO_STEP_MOVE:
        {
            if(abs(m_ptPos.x - m_autoMoveX) < 1)
            {
                m_autoStep = AUTO_STEP_ROT;
                MoveStop();
                SetPos(ccp(m_autoMoveX, m_ptPos.y));
                SetFlip(m_autoFlip);
                /*
                if(abs(m_autoAngle) < 90)
                {
                    SetFlip(false);
                }
                else
                {
                    SetFlip(true);
                }
                 */
                break;
            }
            
            if(m_autoMoveX > (int)m_ptPos.x)
            {
                MoveRight();
            }
            else if(m_autoMoveX < (int)m_ptPos.x)
            {
                MoveLeft();
            }
        }
            break;
        case AUTO_STEP_ROT:
        {
            float rotDiff = m_autoAngle - m_lastAngle;
            
            if(::abs(rotDiff) <=1)
            {
                m_lastAngle = m_autoAngle;
                m_autoStep = AUTO_STEP_POWER;
            }
            else
            {
                m_lastAngle += rotDiff / abs(rotDiff);                
            }
            
            SetCurRotate(m_lastAngle);
        }
            break;
            
        case AUTO_STEP_POWER:
        {
            float powerDiff = m_autoPower - m_curPower;
            
            if(::abs(powerDiff) <=30)
            {
                m_curPower = m_autoPower;
                m_autoStep  = AUTO_STEP_WAIT;
            }
            else
            {
                m_curPower += 30 * powerDiff / abs(powerDiff);                
                SetCurStrength(m_curPower);
            }

			if(-1 == m_nSoundPreshoot)
			{
				m_nSoundPreshoot = SimpleAudioEngine::sharedEngine()->playEffect("Music/preshoot.mp3");
			}
        }
            break;
            
        case AUTO_STEP_WAIT:
        {
            static float waitTimer = 0;
            
            waitTimer += dt;
            
            if(waitTimer > Archer_AUTOSHOOT_WAIT)
            {
                waitTimer = 0;
                m_autoStep  = AUTO_STEP_NONE;
                bFinish = true;
            }

			if(-1 != m_nSoundPreshoot)
			{
				SimpleAudioEngine::sharedEngine()->stopEffect(m_nSoundPreshoot);
			}
        }
            break;
            
        default:
            break;
    }
    
    if(!bFinish)
    {
        if(NULL != m_pCurArrow)
        {
            m_pCurArrow->Prepare(getParent()->convertToNodeSpace(GetLeftHandPos()), GetCurAngle());
        }
        
        return true;
    }
    else
    {
        //Shoot();
        
        return false;
    }
    
}


//--------------------------------------------------------------------------------------------------------------------/
void CArcher::animationChange()
{
    if(m_bUpdateBow)
    {
        m_pSprBow->SetCenter(m_pSprBow->convertToNodeSpace(GetLeftHandPos()));
    }
}

//--------------------------------------------------------------------------------------------------------------------/
CCPoint CArcher::GetLeftHandPos()
{
	return m_apFrames[ARCHER_INDEX_LEFTHAND]->_pSprBone->convertToWorldSpace(CGameGlobal::GetInstance()->AdjustResPos(m_ptLeftHand));
}

//--------------------------------------------------------------------------------------------------------------------/
void CArcher::OnEffectPreShoot()
{
	//可以 再播一次了。
	m_nSoundPreshoot = -1;
}
//--------------------------------------------------------------------------------------------------------------------/
void CArcher::InitState(int id, int type, const ArcherInitData &d, bool bFlip, const BowInfo &bowInfo, const ArrowInfo &arrowInfo, const AABBInfo &aabbInfo)
{
	m_pArcherBatch = CCSpriteBatchNode::batchNodeWithFile("Chars/chars.png");
	addChild(m_pArcherBatch);
    m_ptLeftHand = ccp(d._dataBow._ptPos.x , d._dataHand._ptSize.y - d._dataBow._ptPos.y);
   
    SetCurArrow(arrowInfo);
    
    _BuildArcherFrame(d);
    _InitFrames(m_frameInfo, bFlip, true);
	_InitAABB(aabbInfo);
    _InitBowInfo(bowInfo);
    _SetLocalAnimation(bFlip);
    _SetHurtAnimation(bFlip);
    _SetWalkAnimation(bFlip);
    _SetHurtBodyAnimation(bFlip);
    
    SetAnimation("shoot", 0);
    SetLoop("shoot", true);
	SetLoop("hurt", false);
    SetLoop("walk", true);
    SetLoop("hurtBody", true);
    
	SetValid(true);
    SetFlip(bFlip);
    _InitActions();
    
    if(bFlip)
    {
        SetCurRotate(180);
    }
    else
    {
        SetCurRotate(0);
    }
    
    m_id = id;
	m_type = type;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cocos2d::CCNode *CArcherManager::m_pParent     = NULL;
int              CArcherManager::m_archerOrder = 0;
void CArcherManager::SetSceneInfo(cocos2d::CCNode *pParent, int zOrder)
{
    m_pParent     = pParent;
    m_archerOrder = zOrder;
}

CArcher *CArcherManager::CreateArcher(int id, bool bLeft, int type, int bowID, int arrowID)
{
    if(NULL == m_pParent)
    {
        return NULL;
    }
    CArcher *pRetArcher = CArcher::node();
    m_pParent->addChild(pRetArcher, m_archerOrder);
    
    const BowInfo &bowInfo = CBowManager::GetBowInfo(bowID);
    
    switch (type) 
    {
        case 1:
        {
            ArcherInitData data = 
            {
                // 尺寸 锚点 位置

                {ccp(68, 110), ccp(36, 72), ccp(58, 37), true, "headArcher1.png"},    // 头
                {ccp(102, 108), ccp(70, 103), ccp(0, 0), true, "bodyArcher1.png"},        // 身体
                {ccp(14, 34), ccp(6, 3), ccp(56, 41), true, "armArcher1.png"},           // 胳膊
                {ccp(27, 58), ccp(12, 6), ccp(6, 27), true, "handArcher1.png"},          // 手
                {bowInfo._ptSize, bowInfo._ptAnchor, ccp(12, 48), true, ""}      // 弓
            };
            
            AABBInfo aabbInfo = 
            {
                {MyPoint(-10, 93), MyPoint(10, 63)},
                {MyPoint(-10, 63), MyPoint(10, 10)},
                {MyPoint(10, 0), MyPoint(-10 , 10)}
            };
            
            
            
            strcpy(data._dataBow._name, bowInfo._name);
            
            pRetArcher->InitState(id, type, data, bLeft, CBowManager::GetBowInfo(bowID), CArrowManager::GetArrowInfo(arrowID), aabbInfo);
            
        }
            
            break;
        case 2:
        {
            ArcherInitData data = 
            {
                // 尺寸 锚点 位置
                {ccp(115, 103), ccp(85, 83), ccp(61, 32), true, "headArcher2.png"},    // 头
                {ccp(85, 92), ccp(67, 90), ccp(0, 0), true, "bodyArcher2.png"},        // 身体
                {ccp(11, 28), ccp(4, 2), ccp(62, 38), true, "armArcher2.png"},           // 胳膊
                {ccp(29, 39), ccp(8, 5), ccp(6, 24), true, "handArcher2.png"},          // 手
                {bowInfo._ptSize, bowInfo._ptAnchor, ccp(12, 34), true, ""}      // 弓
            };
            
            strcpy(data._dataBow._name, bowInfo._name);
            
            AABBInfo aabbInfo = 
            {
                {MyPoint(-10, 93), MyPoint(10, 63)},
                {MyPoint(-10, 63), MyPoint(10, 10)},
                {MyPoint(10, 0), MyPoint(-10 , 10)}
            };
            
            
            pRetArcher->InitState(id, type, data, bLeft, CBowManager::GetBowInfo(bowID), CArrowManager::GetArrowInfo(arrowID), aabbInfo);
            
        }
            break;
            
        case 3:
        {
            ArcherInitData data = 
            {
                // 尺寸 锚点 位置
                {ccp(62, 81), ccp(38, 58), ccp(22, 4), true, "headArcher3.png"},    // 头
                {ccp(42, 55), ccp(24, 53), ccp(0, 0), true, "bodyArcher3.png"},        // 身体
                {ccp(10, 26), ccp(5, 2), ccp(22, 7), true, "armArcher3.png"},           // 胳膊
                {ccp(18, 39), ccp(9, 5), ccp(5, 21), true, "handArcher3.png"},          // 手
                {bowInfo._ptSize, bowInfo._ptAnchor, ccp(11, 34), true, ""}      // 弓
            };
            
            strcpy(data._dataBow._name, bowInfo._name);
            
            AABBInfo aabbInfo = 
            {
                {MyPoint(-10, 93), MyPoint(10, 63)},
                {MyPoint(-10, 63), MyPoint(10, 10)},
                {MyPoint(10, 0), MyPoint(-10 , 10)}
            };
            
            
            pRetArcher->InitState(id, type, data, bLeft, CBowManager::GetBowInfo(bowID), CArrowManager::GetArrowInfo(arrowID), aabbInfo);
        }
            break;
            
        case 4:
        {
            ArcherInitData data = 
            {
                // 尺寸 锚点 位置
                {ccp(64, 118), ccp(36, 76), ccp(21, 4), true, "headArcher4.png"},    // 头
                {ccp(36, 59), ccp(21, 53), ccp(0, 0), true, "bodyArcher4.png"},        // 身体
                {ccp(15, 32), ccp(6, 3), ccp(22, 8), true, "armArcher4.png"},           // 胳膊
                {ccp(32, 40), ccp(19, 7), ccp(7, 25), true, "handArcher4.png"},          // 手
                {bowInfo._ptSize, bowInfo._ptAnchor, ccp(19, 32), true, ""}      // 弓
            };
            
            strcpy(data._dataBow._name, bowInfo._name);
            
            AABBInfo aabbInfo = 
            {
                {MyPoint(-10, 93), MyPoint(10, 63)},
                {MyPoint(-10, 63), MyPoint(10, 10)},
                {MyPoint(10, 0), MyPoint(-10 , 10)}
            };
            
            
            pRetArcher->InitState(id, type, data, bLeft, CBowManager::GetBowInfo(bowID), CArrowManager::GetArrowInfo(arrowID), aabbInfo);
        }
            break;
        case 5:
        {
            ArcherInitData data = 
            {
                // 尺寸 锚点 位置
                {ccp(81, 72), ccp(50, 69), ccp(19, 3), true, "headArcher5.png"},    // 头
                {ccp(41, 59), ccp(50, 57), ccp(0, 0), true, "bodyArcher5.png"},        // 身体
                {ccp(14, 31), ccp(7, 3), ccp(17, 7), true, "armArcher5.png"},           // 胳膊
                {ccp(27, 35), ccp(14, 6), ccp(6, 24), true, "handArcher5.png"},          // 手
                {bowInfo._ptSize, bowInfo._ptAnchor, ccp(13, 30), true, ""}      // 弓
            };
            
            strcpy(data._dataBow._name, bowInfo._name);
            
            AABBInfo aabbInfo = 
            {
                {MyPoint(-10, 93), MyPoint(10, 63)},
                {MyPoint(-10, 63), MyPoint(10, 10)},
                {MyPoint(10, 0), MyPoint(-10 , 10)}
            };
            
            
            pRetArcher->InitState(id, type,data, bLeft, CBowManager::GetBowInfo(bowID), CArrowManager::GetArrowInfo(arrowID), aabbInfo);
        }
            break;
        case 6:
        {
            ArcherInitData data = 
            {
                // 尺寸 锚点 位置
                {ccp(69, 76), ccp(40, 73), ccp(20, 3), true, "headArcher6.png"},    // 头
                {ccp(38, 59), ccp(20, 58), ccp(0, 0), true, "bodyArcher6.png"},        // 身体
                {ccp(13, 30), ccp(7, 4), ccp(20, 8), true, "armArcher6.png"},           // 胳膊
                {ccp(28, 41), ccp(14, 6), ccp(7, 23), true, "handArcher6.png"},          // 手
                {bowInfo._ptSize, bowInfo._ptAnchor, ccp(15, 36), true, ""}      // 弓
            };
            
            strcpy(data._dataBow._name, bowInfo._name);
            
            AABBInfo aabbInfo = 
            {
                {MyPoint(-10, 93), MyPoint(10, 63)},
                {MyPoint(-10, 63), MyPoint(10, 10)},
                {MyPoint(10, 0), MyPoint(-10 , 10)}
            };
            
            
            pRetArcher->InitState(id, type, data, bLeft, CBowManager::GetBowInfo(bowID), CArrowManager::GetArrowInfo(arrowID), aabbInfo);
        }
            break;
        default:
            break;
    }
    
    return pRetArcher;
}



















